package game.UI
{
	import flash.display.Sprite;
	import flash.events.Event;
	
	public class ProgressBar
	{
		private static const ANIM_TIME:Number = 500;
		
		private var _sprite:Sprite;
		private var _maxValue:Number = 1;
		private var _currentValue:Number = 0;
		private var _scale:Number;
		private var _visibleScale:Number;
		private var _speed:Number;
		private var _originalSpriteScale:Number;
		private var _lastTime:Number;
		
		public function ProgressBar(sprite:Sprite)
		{
			_sprite = sprite;
			_originalSpriteScale = sprite.scaleX;
		}
		
		public function set maxValue(value:Number):void
		{
			_maxValue = value;
			updateScale();
		}
		
		public function set currentValue(value:Number):void
		{
			_currentValue = value;
			updateScale();
		}
		
		public function get currentValue():Number
		{
			return _currentValue;
		}
		
		public function setValues(currentValue:Number, maxValue:Number, immediately:Boolean = false):void
		{
			_currentValue = currentValue;
			_maxValue = maxValue;
			updateScale(immediately);
		}
		
		private function updateScale(immediately:Boolean = false):void
		{
			if (_maxValue == 0)
			{
				_scale = 0;
			}
			else
			{
				_scale = Math.max(0, Math.min(1, _currentValue / _maxValue));
			}
			_speed = (_scale - _visibleScale) * 1000 / ANIM_TIME;
			
			if (immediately)
			{
				_visibleScale = _scale;
				updateSprite();
			}
			else
			{
				if (!_sprite.hasEventListener(Event.ENTER_FRAME))
				{
					_lastTime = (new Date()).getTime();
					_sprite.addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
				}
			}
		}
		
		private function onEnterFrame(e:Event):void
		{
			var time:Number = (new Date()).getTime();
			var elapsedTime:Number = time - _lastTime;
			
			_visibleScale += _speed * elapsedTime / 1000;
			
			if (((_speed >= 0) && (_visibleScale >= _scale)) || ((_speed < 0) && (_visibleScale < _scale)))
			{
				_visibleScale = _scale;
				_sprite.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
			updateSprite();
			
			_lastTime = time;
		}
		
		private function updateSprite():void
		{
			_sprite.scaleX = _visibleScale * _originalSpriteScale;
		}
		
		public function get barSprite():Sprite
		{
			return _sprite;
		}
		
		public function set sprite(sprite:Sprite):void
		{
			_sprite = sprite;
		}
	}
}